﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Text;

namespace MecPrev.MainApp
{
    static class Class1
    {

        private static DESCryptoServiceProvider _key;
        private static DESCryptoServiceProvider Key
        {
            get
            {
                if (_key == null)
                {
                    _key = new DESCryptoServiceProvider();

                    var keyKey = new byte[] { 90, 2, 54, 65, 34, 3, 43, 43 };
                    byte[] iv = { 10, 20, 30, 40, 50, 60, 70, 80 };
                    _key.Key = keyKey;
                    _key.IV = iv;

                }
                return _key;
            }
        }

        private static string FilePath
        {
            get
            {
                const string fileName = "AdobeCache__";
                var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\" + fileName;
                return path;
            }
        }
        /// <summary>
        /// Ritorna se file è ok.
        /// </summary>
        /// <returns></returns>
        internal static bool IsOk()
        {
            /*
             */

            //SaveLicFile(FilePath, Key, new DateTime(2010, 1, 1));
            var key = Key;

            //---

            //var j222 = EncryptString(TimeSpan.FromDays(31).Ticks.ToString(), key);

            //var jda2 = DecryptString(j222, key);

            //var d = TimeSpan.Parse(jda2);

            //--

            var endDate = GetEndLicenseDate(FilePath, key);

            if (DateTime.Now < endDate)
                return true;

            return false;
        }

        internal static DateTime GetLicenseEnd()
        {
            return GetEndLicenseDate(FilePath, Key);
        }
        private static DateTime GetEndLicenseDate(string filePath, DESCryptoServiceProvider key)
        {
            if (!File.Exists(FilePath))
                SaveLicFile(FilePath, key, DateTime.Now.AddDays(14));

            //  var fi = new FileInfo(filePath) { Attributes = FileAttributes.Hidden };

            //  fi.Decrypt();

            using (var fs = new FileStream(filePath, FileMode.Open))
            {
                var ticksD = new List<string>();
                using (var w = new StreamReader(fs, Encoding.ASCII))
                {
                    while (w.Peek() >= 0)
                    {
                        ticksD.Add(w.ReadLine());
                    }
                }

                //var b = new byte[ticksD.Count()];

                //for (int i = 0; i < ticksD.Count(); i++)
                //{
                //    b[i] = byte.Parse(ticksD[i]);
                //}

                //var o = Decrypt(b, key);

                //var ticks = Int64.Parse(o);

                var ticks = Int64.Parse(ticksD.First());

                return new DateTime(ticks);
            }

        }

        //private static void CreateLicFile(string fp, DESCryptoServiceProvider key)
        //{
        //    var date = DateTime.Now.AddDays(14);

        //    var bufferDate = Encrypt(date.Ticks.ToString(), key);

        //    using (var fs = new FileStream(fp, FileMode.Create))
        //    {
        //        using (var w = new StreamWriter(fs, Encoding.ASCII))
        //        {
        //            foreach (var b in bufferDate)
        //            {
        //                w.WriteLine(b);
        //            }
        //        }
        //    }

        //    var fi = new FileInfo(fp) { Attributes = FileAttributes.Hidden };

        //    fi.Encrypt();

        //    fi.IsReadOnly = true;
        //}

        private static void SaveLicFile(string fp, DESCryptoServiceProvider key, DateTime date)
        {
            var bufferDate = EncryptString(date.Ticks.ToString(), key);


            using (var fs = new FileStream(fp, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                using (var w = new StreamWriter(fs, Encoding.ASCII))
                {
                    w.WriteLine(date.Ticks.ToString());
                    //foreach (var b in bufferDate)
                    //{
                    //    w.WriteLine(b);
                    //}
                }
            }

            new FileInfo(fp) { Attributes = FileAttributes.Hidden };

        }

        private static string EncryptString(string plainText, SymmetricAlgorithm key)
        {
            // Create a memory stream.
            var ms = new MemoryStream();

            // Create a CryptoStream using the memory stream and the
            // CSP DES key.
            var encStream = new CryptoStream(ms, key.CreateEncryptor(), CryptoStreamMode.Write);

            // Create a StreamWriter to write a string
            // to the stream.
            var sw = new StreamWriter(encStream);

            // Write the plaintext to the stream.
            sw.WriteLine(plainText);

            // Close the StreamWriter and CryptoStream.
            sw.Close();
            encStream.Close();

            // Get an array of bytes that represents
            // the memory stream.
            var buffer = ms.ToArray();

            var enc = Encoding.Default;
            var myString = enc.GetString(buffer);

            // Close the memory stream.
            ms.Close();

            // Return the encrypted byte array.
            return myString;
        }

        //private static byte[] Encrypt(string plainText, SymmetricAlgorithm key)
        //{
        //    // Create a memory stream.
        //    var ms = new MemoryStream();

        //    // Create a CryptoStream using the memory stream and the
        //    // CSP DES key.
        //    var encStream = new CryptoStream(ms, key.CreateEncryptor(), CryptoStreamMode.Write);

        //    // Create a StreamWriter to write a string
        //    // to the stream.
        //    var sw = new StreamWriter(encStream);

        //    // Write the plaintext to the stream.
        //    sw.WriteLine(plainText);

        //    // Close the StreamWriter and CryptoStream.
        //    sw.Close();
        //    encStream.Close();

        //    // Get an array of bytes that represents
        //    // the memory stream.
        //    var buffer = ms.ToArray();

        //    // Close the memory stream.
        //    ms.Close();

        //    // Return the encrypted byte array.
        //    return buffer;
        //}

        //Decrypt the byte array.
        private static string Decrypt(byte[] cypherText, SymmetricAlgorithm key)
        {
            var encoding = Encoding.Default;

            // Create a memory stream to the passed buffer.
            var ms = new MemoryStream(cypherText);

            // Create a CryptoStream using the memory stream and the
            // CSP DES key.
            var encStream = new CryptoStream(ms, key.CreateDecryptor(), CryptoStreamMode.Read);

            // Create a StreamReader for reading the stream.
            var sr = new StreamReader(encStream);

            // Read the stream as a string.
            var val = sr.ReadLine();

            // Close the streams.
            sr.Close();
            encStream.Close();
            ms.Close();

            return val;
        }

        private static string DecryptString(string stringEnc, SymmetricAlgorithm key)
        {
            var encoding = Encoding.Default;

            var cypherText = encoding.GetBytes(stringEnc);

            // Create a memory stream to the passed buffer.
            var ms = new MemoryStream(cypherText);

            // Create a CryptoStream using the memory stream and the
            // CSP DES key.
            var encStream = new CryptoStream(ms, key.CreateDecryptor(), CryptoStreamMode.Read);

            // Create a StreamReader for reading the stream.
            var sr = new StreamReader(encStream);

            // Read the stream as a string.
            var val = sr.ReadLine();

            // Close the streams.
            sr.Close();
            encStream.Close();
            ms.Close();

            return val;
        }

        /// <summary>
        /// Metodo che aggiorna licenza.
        /// </summary>
        /// <returns>0 - Ok 1- Chiave Non Valida 2 - Scaduta 3 - errore generale</returns>
        internal static int InsertLicenseKey(string licenseKey)
        {
            try
            {
                // assumo che ho già controllato connessione.
                using (var svc = new MecPrevSvc.Service1Client())
                {
                    var m = RptSen.ReportGenerator.PcId.GetPcId();

                    var endDate = GetEndLicenseDate(FilePath, Key);

                    var result = svc.GetLicenseInfo(licenseKey, m.MacAddress, endDate);

                    //Chiave non inserita nel database
                    if (result.IncorrectKey)
                        return 1;

                    //Chiave scaduta
                    if (endDate > result.EndLicenseTime)
                        return 2;

                    //Chiave ok
                    if (result.EndLicenseTime >= endDate)
                    {
                        SaveLicFile(FilePath, Key, result.EndLicenseTime);
                        return 0;
                    }
                }
            }
            catch (Exception exception)
            {
                return 3;
            }

            return 3;
        }

        //   var key = Key;
        //   var l = DecryptString(coded, key);

        //   DateTime timeSpan;
        //   if (!DateTime.TryParse(l, out timeSpan))
        //   {
        //       return false;
        //   }

        //   var endDate = GetEndLicenseDate(FilePath, key);

        //   /*
        //    * se data è 
        //    */
        //   var dateTime = endDate;

        //   var now = DateTime.Now;

        //   if (now > dateTime)
        //       dateTime = now;

        ////   dateTime = dateTime.Add(timeSpan);

        //   SaveLicFile(FilePath, key, dateTime);

        //   return true;


    }
}
